﻿using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace Gmantis.Controls.DataGrid
{
    [TemplatePart(Name = "ToggleGroup", Type = typeof(DataGridToggleGroupButton)), TemplatePart(Name = "GroupName", Type = typeof(ContentPresenter))]
    public class DataGridGroupRowPresenter : DataGridSelectableRowPresenter
    {
        // Fields
        internal ContentPresenter _elementGroupName;
        internal DataGridToggleGroupButton _elementToggleGroup;
        internal bool _isLoaded;
        public static readonly DependencyProperty ButtonBackgroundProperty = DependencyProperty.Register("ButtonBackground", typeof(Brush), typeof(DataGridGroupRowPresenter), null);
        public static readonly DependencyProperty ButtonForegroundProperty = DependencyProperty.Register("ButtonForeground", typeof(Brush), typeof(DataGridGroupRowPresenter), null);
        public static readonly DependencyProperty GroupContentMarginProperty = DependencyProperty.Register("GroupContentMargin", typeof(Thickness), typeof(DataGridGroupRowPresenter), null);
        public static readonly DependencyProperty GroupContentProperty = DependencyProperty.Register("GroupContent", typeof(object), typeof(DataGridGroupRowPresenter), null);
        internal const string GroupNameElementName = "GroupName";
        public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register("IsChecked", typeof(bool), typeof(DataGridGroupRowPresenter), null);
        internal const string ToggleGroupElementName = "ToggleGroup";

        // Methods
        public DataGridGroupRowPresenter()
        {
            base.DefaultStyleKey = typeof(DataGridGroupRowPresenter);
            this.SetCustomDefaultValues();
        }

        private T GetTemplateChild<T>(string childName, bool required, ref string errors) where T : class
        {
            DependencyObject templateChild = base.GetTemplateChild(childName);
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "template part", childName, templateChild, required, ref errors);
            return (templateChild as T);
        }

        private static Storyboard GetTemplateChildResource(FrameworkElement root, string resourceName, bool required, ref string errors)
        {
            return GetTemplateChildResource<Storyboard>(root, resourceName, required, ref errors);
        }

        private static T GetTemplateChildResource<T>(FrameworkElement root, string resourceName, bool required, ref string errors) where T : class
        {
            object child = root.Resources[resourceName];
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "resource", resourceName, child, required, ref errors);
            return (child as T);
        }

        private void InitializeGroupNamePart()
        {
            if (DesignerProperties.GetIsInDesignMode(this))
            {
                this._elementGroupName.Content = "This is the group name";
            }
            else
            {
                this._elementGroupName.SetBinding<DataGridGroupRowPresenter>(ContentPresenter.ContentProperty, this, x => x.GroupContent);
            }
        }

        private void InitializeToggleGroupPart()
        {
            if (!DesignerProperties.GetIsInDesignMode(this))
            {
                this._elementToggleGroup.IsThreeState = false;
                Binding binding = new Binding
                {
                    Mode = BindingMode.TwoWay
                };
                this._elementToggleGroup.SetBinding(ToggleButton.IsCheckedProperty, binding.From<DataGridGroupRowPresenter>(this, x => x.IsChecked));
            }
        }

        public override void OnApplyTemplate()
        {
            string errors = string.Empty;
            base.OnApplyTemplate();
            this._isLoaded = true;
            this._elementGroupName = this.GetTemplateChild<ContentPresenter>("GroupName", true, ref errors);
            if (this._elementGroupName != null)
            {
                this.InitializeGroupNamePart();
            }
            this._elementToggleGroup = this.GetTemplateChild<DataGridToggleGroupButton>("ToggleGroup", true, ref errors);
            if (this._elementToggleGroup != null)
            {
                this.InitializeToggleGroupPart();
            }
            if (!string.IsNullOrEmpty(errors))
            {
                this._isLoaded = false;
                if ((base.Template != null) && !PlatformIndependent.IsInDesignMode(this))
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Template cannot be applied to DataGridGroupRowPresenter.\nDetails: {0}", new object[] { errors }));
                }
            }
        }

        private void SetCustomDefaultValues()
        {
        }

        // Properties
        public Brush ButtonBackground
        {
            get
            {
                return (Brush)base.GetValue(ButtonBackgroundProperty);
            }
            set
            {
                base.SetValue(ButtonBackgroundProperty, value);
            }
        }

        public Brush ButtonForeground
        {
            get
            {
                return (Brush)base.GetValue(ButtonForegroundProperty);
            }
            set
            {
                base.SetValue(ButtonForegroundProperty, value);
            }
        }

        public object GroupContent
        {
            get
            {
                return base.GetValue(GroupContentProperty);
            }
            set
            {
                base.SetValue(GroupContentProperty, value);
            }
        }

        public Thickness GroupContentMargin
        {
            get
            {
                return (Thickness)base.GetValue(GroupContentMarginProperty);
            }
            set
            {
                base.SetValue(GroupContentMarginProperty, value);
            }
        }

        public bool IsChecked
        {
            get
            {
                return (bool)base.GetValue(IsCheckedProperty);
            }
            set
            {
                base.SetValue(IsCheckedProperty, value);
            }
        }
    }
}
